package com.sqlist.share.connection;

import android.os.Message;
import android.os.SystemClock;
import android.util.Log;

import com.sqlist.share.dto.MessageDTO;
import com.sqlist.share.util.Callback;
import com.sqlist.share.util.Const;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;

/**
 * Created by SqList on 2018/6/11.
 */

public class Client {

    private static final String TAG = "Share - Client";

    private final String host = Const.HOST;
    private final int port = Const.NETTY_PORT;

    private static final Client INSTANCE = new Client();

    public static Client getInstance() {
        return INSTANCE;
    }

    private EventLoopGroup group;
    private ChannelFuture channelFuture;
    private Channel channel;

    private int reconnectCount = 0;
    // 重连等待时间
    private int reconnectIntervalTime = 5000;

    // 是否已连接
    private boolean isConnect = false;
    // 是否正在进行连接
    private boolean isConnecting = false;
    // 是否需要重连
    private boolean isReconnect = false;

    private Message message;

    public Client() {
    }

    public void connect() {
//        synchronized (Client.class) {
            if (!isConnect) {
                Log.d(TAG, "==============准备启动==============");
                Log.d(TAG, "==============正在进行连接==============");
                isConnecting = true;
                group = new NioEventLoopGroup();
                try {
                    Bootstrap bootstrap = new Bootstrap();
                    bootstrap.group(group)
                            .channel(NioSocketChannel.class)
                            .handler(new ClientInitializer());

                    channelFuture = bootstrap.connect(host, port).addListener(new ChannelFutureListener() {
                        @Override
                        public void operationComplete(ChannelFuture future) throws Exception {
                            if (future.isSuccess()) {
                                Log.i(TAG, "==============连接成功==============");
                                isConnect = true;
                                isReconnect = true;
                                channel = future.channel();
                                reconnectCount = 0;

//                                if (callback != null) {
//                                    callback.onSuccess(null);
//                                }
                            } else {
                                Log.i(TAG, "==============连接失败==============");
                                isConnect = false;
                                isReconnect = false;

//                                if (callback != null) {
//                                    callback.onFailed(null);
//                                }
                                future.cause().printStackTrace();
                            }
                            isConnecting = false;
                        }
                    }).sync();
                    Log.d(TAG, "==============启动完毕==============");

                    channelFuture.channel().closeFuture().sync();
                } catch (InterruptedException e) {
                    Log.i(TAG, "服务器连接失败");
                    disConnect();
                    e.printStackTrace();
                } finally {
                    isConnect = false;
                    if (null != channelFuture) {
                        if (channelFuture.channel() != null && channelFuture.channel().isOpen()) {
                            channelFuture.channel().close();
                        }
                    }
                    group.shutdownGracefully();
//                    reConnect();
                }
            }
//        }
    }

    public void reConnect() {
        Log.i(TAG, "reConnect");
        if (isReconnect && reconnectCount < Const.NETTY_RECONNECT_COUNT && !isConnect && !isConnecting) {
            SystemClock.sleep(reconnectIntervalTime);
            if (isReconnect && reconnectCount < Const.NETTY_RECONNECT_COUNT && ! isConnect && !isConnecting) {
                Log.i(TAG, "==============第" + reconnectCount++ + "次重新连接==============");
                connect();
            }
        }
    }

    // 断开连接
    public void disConnect() {
        Log.i(TAG, "disConnect");
        isReconnect = false;
        group.shutdownGracefully();
        channel = null;
    }

    // 发送消息
    public void sendMessageDTO(String messageString) {
        if (channel != null && isConnect) {
            Log.i(TAG, "sendMessageDTO: " + messageString);
            byte[] req = (messageString + "|").getBytes();
            ByteBuf byteBuf = Unpooled.buffer(req.length);
            byteBuf.writeBytes(req);
            channel.writeAndFlush(byteBuf);
        }
    }

    public Channel getChannel() {
        return channel;
    }
}
